﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;

using cit.CopyDetection.DataObject;

namespace cit.CopyDetection.DatabaseAccess
{
    /// <summary>
    /// Lớp truy cập CSDL cho bảng "PostingList" và "Stopwords"
    /// </summary>
    public class TermDataAccess: ObjectDataAccess
    {
        #region Stopwords table


        /// <summary>
        /// Lấy về danh sách các từ rỗng nghĩa
        /// </summary>
        /// <returns>Danh sách các từ rỗng nghĩa</returns>
        public static List<string> GetStopwords()
        {
            List<string> stopwords = new List<string>();
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select * from stopwords";
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, null, connection);

                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        stopwords.Add(reader.GetString(0).Trim());
                    }
                }
                connection.Close();

                return stopwords;
            }
        }


        #endregion


        #region PostingList table


        /// <summary>
        /// Lấy về thông tin chi tiết của tập từ vựng
        /// </summary>
        /// <returns>Thông tin chi tiết tập từ vựng</returns>
        public static List<Term> GetTerms()
        {
            List<Term> terms = new List<Term>();
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "SELECT term, count(*), sum(termfreq) FROM postinglist GROUP BY term";
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, null, connection);

                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        terms.Add(new Term()
                        {
                            WordString = reader.GetString(0).Trim(),
                            ParagraphFrequency = reader.GetInt32(1),
                            GlobalFrequency = reader.GetInt32(2)
                        });
                    }
                }
                connection.Close();

                return terms;
            }
        }

        /// <summary>
        /// Lấy về thông tin chi tiết của tập từ vựng của một đoạn văn bản
        /// </summary>
        /// <param name="paragraph">Đoạn văn bản cần lấy về tập các từ</param>
        /// <returns>Danh sách các từ trong đoạn văn bản</returns>
        public static List<Term> GetTerms(Paragraph paragraph)
        {
            List<Term> terms = new List<Term>();
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "SELECT a.term, parafreq, termfreq FROM postinglist AS a, (SELECT term, count(*) AS parafreq FROM postinglist GROUP BY term) AS b WHERE paranum=? And docname=? And a.term=b.term GROUP BY a.term, parafreq, termfreq";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                        new OdbcParameter("@paranum", OdbcType.Int){Value = paragraph.OrdinalNumber},
                                        new OdbcParameter("@docname", OdbcType.Text){Value = paragraph.DocumentName}};
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, parameters, connection);

                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        terms.Add(new Term()
                        {
                            WordString = reader.GetString(0).Trim(),
                            ParagraphFrequency = reader.GetInt32(1),
                            GlobalFrequency = reader.GetInt32(2)
                        });
                    }
                }
                connection.Close();

                return terms;
            }
        }

        /// <summary>
        /// Xóa từ trong đoạn văn bản
        /// </summary>
        /// <param name="paragraph">Đoạn văn bản cần xóa từ</param>
        /// <returns>Số dòng tác động bởi câu lệnh</returns>
        public static int RemoveTerms(Paragraph paragraph)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlDeleteCommand = "delete from postinglist where docname = ? and paranum = ?";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                        new OdbcParameter("@docname", OdbcType.Text){Value = paragraph.DocumentName},
                                        new OdbcParameter("@paranum", OdbcType.Int){Value = paragraph.OrdinalNumber}};
                return OdbcExecuteNonQuery(sqlDeleteCommand, parameters, connection);
            }
        }

        /// <summary>
        /// Ghi nhận sự xuất hiện của một thuật ngữ trong đoạn văn bản
        /// </summary>
        /// <param name="term">Thuật ngữ</param>
        /// <param name="paragraph">Đoạn văn bản</param>
        /// <returns>Số dòng tác động bởi câu lệnh</returns>
        public static int InsertPostingList(Term term, Paragraph paragraph)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlUpdateCommand = "insert into postinglist values (?, ?, ?, ?)";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                               new OdbcParameter("@term", OdbcType.Text){Value = term.WordString},
                                               new OdbcParameter("@paranum", OdbcType.Int){Value = paragraph.OrdinalNumber},
                                               new OdbcParameter("@docname", OdbcType.Text){Value = paragraph.DocumentName},
                                               new OdbcParameter("@termfreq", OdbcType.Int){Value = term.GlobalFrequency}};
                return OdbcExecuteNonQuery(sqlUpdateCommand, parameters, connection);
            }
        }

        /// <summary>
        /// Lấy về số lần xuất hiện của từ trong các đoạn văn bản
        /// </summary>
        /// <param name="term">Từ cần lấy tần suất</param>
        /// <returns>Danh sách các giá trị tuần suất của từ</returns>
        public static List<int> GetTermFrequencies(Term term)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select termfreq from postinglist where term = ?";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                        new OdbcParameter("@term", OdbcType.Text){Value = term.WordString}};
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, parameters, connection);

                connection.Open();
                List<int> freqs = new List<int>();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        freqs.Add(reader.GetInt32(0));
                    }
                }
                connection.Close();

                return freqs;
            }
        }

        
        #endregion
    }
}
